#ifndef ENTITY_HPP_GUARD
#define ENTITY_HPP_GUARD

#include "logger.hpp"

#include <string>
#include <vector>

namespace mashine { namespace kb {

template<typename _Parameter = void> struct Entity
{
public:
	/**
	 * constructor base knowlege base entity. it calling throws 
	 * illegal state exception
	 */
	Entity(std::string name, std::vector<_Parameter> params)
	{
		// if (!(validateName(name) && validateParam(params)))
		// {
			// APP_LOGGER(info) << "Entity with name {" << name << "} validation failed";
			
			// // TODO add throw exception if something else
		// }
		
		this->name = name;
		this->params = params;
		
		//APP_LOGGER(info) << "KbEntity {" << toString() << "} instantiated";
	}
	
	/**
	 * defaut copy-constructor
	 */
	Entity(Entity<_Parameter> const & entity)
	{
		this->name = std::string(entity.getName());
		this->params = std::vector<_Parameter>(entity.getParams());
	
		// APP_LOGGER(info) << "KbEntity {" << entity.toString() << "} copied";
	}


	/**
	 * default destructor for all Entity child classes
	 */
	virtual ~Entity()
	{
		// APP_LOGGER(debug) << "KbEntity {" << toString() << "} begins to break down";
	}

	/**
	 * name of entity
	 */
	virtual std::string getName() const
	{ 
		return name; 
	}


	/**
	 * set name of entity
	 */
	virtual void setName(std::string name)
	{
		this->name = name;
	}

	/**
	 * return params of knowlege base entity. in the simplest case
	 * this string. in eny cases it may be Entity-child clases
	 */
	virtual std::vector<_Parameter> const & getParams() const
	{ 
		return params; 
	}

	/**
	 * setter method for set parameters
	 */
	virtual void setParams(std::vector<_Parameter> params)
	{
		this->params = params;
	}
	
	/**
	 * return string representation object
	 */
	virtual std::string toString() const
	{
		return name + "!";
	}
	
	virtual bool equals(Entity<_Parameter> obj) const
	{	
	}

protected:
	/**
	 * Don't call this constructor manualy
	 */
	Entity() {}
	
	/**
	 * need owerride this method in child class
	 * to correct work Entity constructor
	 */
	virtual bool validateName() const
	{
		APP_LOGGER(warning) << "if yow see this message, it's not ok. you must owerride method validateName()";

		return false;
	}
	
	/**
	 * need owerride this method in child class 
	 * to correct work Entity constructor
	 */
	virtual bool validateParam() const
	{
		APP_LOGGER(warning) << "if yow see this message, it's not ok. you must owerride method validateParam()";

		return false;
	}

	std::string name;
	std::vector<_Parameter> params;		// !!!!!!!!!! NEED TO MOVE THIS TO Rule Literal and Analogy classes
};

}}

#endif